home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / ch_3.2 / lpfltr / lpfltr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  6.0 KB  |  190 lines

  1. /* 
  2.  * lpfltr.c
  3.  * 
  4.  * Practical Algorithms for Image Analysis
  5.  * 
  6.  * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
  7.  */
  8.  
  9. /* LPFLTR:      program performs low-pass filtering on image
  10.  *                usage: lpfltr inimg outimg
  11.  *                       [-f freq <0-0.5>] [-s fltrSize] [-q quickFlag] [-L]
  12.  *
  13.  */
  14.  
  15. #define DFLT_CUTOFF 0.5         /* reduction by 2 is default cutoff */
  16. #define RECT_CUTOFF 0.443883    /* factor to calc. 3dB cutoff freq */
  17. #define GAUSS_CUTOFF 0.832555   /* factor to calc. 3dB cutoff freq */
  18. #define ROUNDUP 0.99999         /* for rounding up integer */
  19. #define NORM 100.0              /* normaliz. factor to integerize */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <images.h>
  24. #include <tiffimage.h>
  25. #include <math.h>
  26. #include <string.h>
  27. extern void print_sos_lic ();
  28.  
  29. long convolve1 (Image *, long *, long);
  30. long smooth (Image *, long);
  31. long input (int, char **, double *, long *, short *);
  32. long usage (short);
  33.  
  34. main (argc, argv)
  35.      int argc;
  36.      char *argv[];
  37. {
  38.   Image *imgIO;                 /* I/O image structure */
  39.   long width, height;           /* image size */
  40.   double cutoff;                /* low-pass cutoff frequency */
  41.   long fltrSize;                /* filter mask size */
  42.   double stdDev;                /* std. deviation param. of Gaussian */
  43.   long *fltr;                   /* 1D filter mask */
  44.   long midFltr;                 /* middle filter coefficient */
  45.   short quickFlag;              /* for quick and dirty rect. filter */
  46.   long i;
  47.  
  48.   if (input (argc, argv, &cutoff, &fltrSize, &quickFlag) < 0)
  49.     return (-1);
  50.  
  51. /* allocate input and output image memory */
  52.   imgIO = ImageIn (argv[1]);
  53.   height = ImageGetHeight (imgIO);
  54.   width = ImageGetWidth (imgIO);
  55.   printf ("Image size is %dx%d.\n", width, height);
  56.  
  57. /* determine filter size and coefficients */
  58.   if (quickFlag) {              /* rectangular filter window */
  59.     if (fltrSize == 0)
  60.       fltrSize = (long) (RECT_CUTOFF / cutoff + ROUNDUP);
  61.   }
  62.   else {                        /* Gaussian filter window */
  63.     stdDev = GAUSS_CUTOFF / cutoff;
  64.     if (fltrSize == 0)
  65.       fltrSize = (long) (3.0 / (2.0 * cutoff) + 0.5);
  66.   }
  67.   if ((fltrSize % 2) == 0)
  68.     fltrSize += 1;
  69.   printf ("Filter cutoff is %5.2f and filter size is %dx%d.\n",
  70.           cutoff, fltrSize, fltrSize);
  71.  
  72. /* calculate Gaussian filter coefficients */
  73.   if (!quickFlag) {
  74.     fltr = (long *) calloc (fltrSize, sizeof (*fltr));
  75.     midFltr = fltrSize / 2;
  76.     for (i = 0; i <= midFltr; i++)
  77.       fltr[i + midFltr] = fltr[midFltr - i]
  78.         = (long) (NORM * exp (-i * i / (2.0 * stdDev * stdDev)) + 0.5);
  79.   }
  80.  
  81. /* perform filtering */
  82.   if (quickFlag)
  83.     smooth (imgIO, fltrSize);
  84.   else
  85.     convolve1 (imgIO, fltr, fltrSize);
  86.  
  87. /* output low-passed image */
  88.   ImageOut (argv[2], imgIO);
  89.  
  90.   return (0);
  91. }
  92.  
  93.  
  94. /* USAGE:       function gives instructions on usage of program
  95.  *                    usage: usage (flag)
  96.  *              When flag is 1, the long message is given, 0 gives short.
  97.  */
  98.  
  99. long
  100. usage (flag)
  101.      short flag;                /* flag =1 for long message; =0 for short message */
  102. {
  103.  
  104. /* print short usage message or long */
  105.   printf ("USAGE: lpfltr inimg outimg [-f CUTOFF <%4.2f>] [-s FLTRSIZE <odd>]\n", DFLT_CUTOFF);
  106.   printf ("                           [-q QUICK_FLAG] [-L]\n");
  107.   if (flag == 0)
  108.     return (-1);
  109.  
  110.   printf ("\nlpfltr performs low-pass filtering upon image\n");
  111.   printf ("using filter window of chosen size; the default is to use\n");
  112.   printf ("a Gaussian-shaped filter window.\n\n");
  113.   printf ("ARGUMENTS:\n");
  114.   printf ("    inimg: input image filename (TIF)\n");
  115.   printf ("   outimg: output image filename (TIF)\n\n");
  116.   printf ("OPTIONS:\n");
  117.   printf ("     -f CUTOFF: <0.0 to 0.5> is the fraction of the passband;\n");
  118.   printf ("                the default is 0.25, that is half of original passband.\n");
  119.   printf ("  -s FLTR_SIZE: is the size of the filter; this will override\n");
  120.   printf ("                the size that would otherwise be automatically set from\n");
  121.   printf ("                the cutoff frequency; this size must be odd.\n");
  122.   printf (" -q QUICK_FLAG: for quick (and dirty) rectangular filtering;\n");
  123.   printf ("                NOTE: specifying both cutoff frequency and filter\n");
  124.   printf ("                size are redundant for the rectangular filter;\n");
  125.   printf ("                the cutoff is used if both are specified.\n");
  126.   printf ("            -L: print Software License for this module\n");
  127.   return (-1);
  128. }
  129.  
  130.  
  131. /* INPUT:       function reads input parameters
  132.  *                  usage: input (argc, argv, &cutoff, &fltrSize, &quickFlag)
  133.  */
  134.  
  135. #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
  136.  
  137. long
  138. input (argc, argv, cutoff, fltrSize, quickFlag)
  139.      int argc;
  140.      char *argv[];
  141.      double *cutoff;            /* cutoff frequency (0.0 to 1.0) */
  142.      long *fltrSize;            /* sidelength of square filter */
  143.      short *quickFlag;          /* for quick and dirty rect. filter */
  144. {
  145.   long n;
  146.  
  147.   if (argc < 3)
  148.     USAGE_EXIT (1);
  149.  
  150.   *cutoff = 0.0;
  151.   *fltrSize = 0;
  152.   *quickFlag = 0;
  153.  
  154.   for (n = 3; n < argc; n++) {
  155.     if (strcmp (argv[n], "-f") == 0) {
  156.       if (++n == argc || argv[n][0] == '-')
  157.         USAGE_EXIT (-1);
  158.       *cutoff = atof (argv[n]);
  159.       if (*cutoff < 0.0 || *cutoff > 0.5) {
  160.         printf ("Cutoff frequency must be between 0.0 and 0.5.\n");
  161.         USAGE_EXIT (-1);
  162.       }
  163.     }
  164.     else if (strcmp (argv[n], "-s") == 0) {
  165.       if (++n == argc || argv[n][0] == '-')
  166.         USAGE_EXIT (-1);
  167.       *fltrSize = atol (argv[n]);
  168.     }
  169.     else if (strcmp (argv[n], "-q") == 0)
  170.       *quickFlag = 1;
  171.     else if (strcmp (argv[n], "-L") == 0) {
  172.       print_sos_lic ();
  173.       exit (0);
  174.     }
  175.     else
  176.       USAGE_EXIT (-1);
  177.   }
  178.  
  179. /* resolve any redundancy for rectangular filter parameter specification */
  180.   if ((*quickFlag) && (*fltrSize != 0 && *cutoff != 0.0)) {
  181.     printf ("For rectangular filter, specifying filter cutoff and size\n");
  182.     printf ("are redundant. Program is using size -- not cutoff -- here.\n");
  183.   }
  184.  
  185.   if (*cutoff == 0.0)
  186.     *cutoff = DFLT_CUTOFF;
  187.  
  188.   return (0);
  189. }
  190.